package cc.zy.base.hr.controller;

import cc.zy.base.common.annotation.ControllerEndpoint;
import cc.zy.base.common.controller.BaseController;
import cc.zy.base.common.entity.FebsConstant;
import cc.zy.base.common.entity.FebsResponse;
import cc.zy.base.common.entity.QueryRequest;
import cc.zy.base.common.exception.FebsException;
import cc.zy.base.common.utils.DateUtil;
import cc.zy.base.common.utils.FebsUtil;
import cc.zy.base.hr.entity.StaffLabel;
import cc.zy.base.hr.service.IStaffLabelService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.wuwenze.poi.ExcelKit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author ljy
 * @time 2022/03/05 10:32:24
 */
@Controller("hrView")
@Slf4j
@Validated
@RequiredArgsConstructor
public class StaffLabelController extends BaseController {

    @Autowired
    private final IStaffLabelService staffLabelService;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 数据库起始id
     */
    private static final Integer MIN_TAG_ID = 60000;

    /**
     * 数据库最大id
     */
    private static final Integer MAX_TAG_ID = 63000;

    /**
     * 标签名的验证规则
     */
    private static final String TAG_NAME_REGEX = "[0-9a-zA-Z\u4e00-\u9fa5]{2,32}";

    /**
     * 标签备注格式
     */
    private static final Integer REMARK_MAX_LENGTH = 100;

    /**
     * 打开增加模态框
     * @return
     */
    @GetMapping(FebsConstant.VIEW_PREFIX + "staffLabel/staffLabelAdd")
    public String staffLabelAdd() {
        return FebsUtil.hrView("staffLabel/staffLabelAdd");
    }


    /**
     * 打开修改模态框，将对象传到修改页面实现回显
     * @param id
     * @param model
     * @return
     */
    @GetMapping(FebsConstant.VIEW_PREFIX + "staffLabel/staffLabelUpdate/{id}")
    public String staffLabelUpdate(@PathVariable Integer id, Model model) {
        saveStaffLabelEditing(id);
        resolveStaffLabelModel(id, model, false);
        return FebsUtil.hrView("staffLabel/staffLabelUpdate");
    }

    /**
     * 打开详情页面
     * @param id
     * @param model
     * @return
     */
    @GetMapping(FebsConstant.VIEW_PREFIX + "staffLabel/detail/{id}")
    public String collegeDetail(@PathVariable Integer id, Model model) {
        resolveStaffLabelModel(id, model, true);
        return FebsUtil.hrView("staffLabel/staffLabelDetail");
    }

    /**
     * 查找标签
     * @param request
     * @param staffLabel
     * @return
     */
    @GetMapping("staffLabel/list")
    @ResponseBody
    public FebsResponse staffLabelList(QueryRequest request, StaffLabel staffLabel) {
        log.debug("前台传来的对象是：" + staffLabel);
        Map<String, Object> dataTable = getDataTable(staffLabelService.getStaffLabels(request, staffLabel));
        return new FebsResponse().success().data(dataTable);
    }

    /**
     * 新增标签
     * @param staffLabel
     * @return
     */
    @PostMapping("staffLabel/add")
    @ResponseBody
    @ControllerEndpoint(operation = "新增标签", exceptionMessage = "新增标签异常")
    public FebsResponse addStaffLabel(@Valid StaffLabel staffLabel) {
        // 标签内容后端验证
        if (!validateStaffLabel(staffLabel)) {
            return new FebsResponse().fail().message("标签信息不符合要求");
        }

        // 查找目前所有的id,得到新创建的标签id
        List<StaffLabel> staffLabels = staffLabelService.getStaffLabels(new StaffLabel());
        List<Integer> idList = new ArrayList<>();

        for (StaffLabel staffLabel1 : staffLabels) {
            idList.add(staffLabel1.getId());
        }

        Collections.sort(idList);
        Integer lastId = idList.get(idList.size() - 1);
        Integer count = 0;

        if (MIN_TAG_ID + idList.size() - 1 == lastId) {
            staffLabel.setId(lastId + 1);
        } else if (lastId == null || lastId < MIN_TAG_ID) {
            staffLabel.setId(MIN_TAG_ID);
        } else if (lastId >= MIN_TAG_ID && lastId < MAX_TAG_ID) {
            for (int j = 0; j < idList.size(); j++) {
                if (!idList.get(count).equals(MIN_TAG_ID + count)) {
                    break;
                }
                count++;
            }
            staffLabel.setId(count + MIN_TAG_ID);
        } else {
            return new FebsResponse().fail();
        }
        staffLabel.setCreateUserId(FebsUtil.getCurrentUser().getUserId());
        staffLabel.setLastModifyUserId(FebsUtil.getCurrentUser().getUserId());
        staffLabelService.createStaffLabel(staffLabel);
        return new FebsResponse().success();
    }

    /**
     * 删除标签
     * @param staffLabelIds
     * @return
     */
    @GetMapping("staffLabel/delete/{staffLabelIds}")
    @ControllerEndpoint(operation = "删除标签", exceptionMessage = "删除标签异常")
    @ResponseBody
    public FebsResponse deleteStaffLabels(@NotBlank(message = "{required}") @PathVariable String staffLabelIds) {
        String[] ids = staffLabelIds.split(StringPool.COMMA);
        staffLabelService.deleteStaffLabels(ids);
        return new FebsResponse().success();
    }

    /**
     * 修改标签
     * @param staffLabel
     * @return
     */
    @PostMapping("staffLabel/update")
    @ControllerEndpoint(operation = "修改标签", exceptionMessage = "修改标签信息异常")
    @ResponseBody
    public FebsResponse updateStaffLabel(@Valid StaffLabel staffLabel) {
        // 验证id是否被修改
        String idOnEditing = "" + redisTemplate.opsForValue().get("" + FebsUtil.getCurrentUser().getUserId());

        if (staffLabel.getId() == null || !idOnEditing.equals(staffLabel.getId() + "")) {
            return new FebsResponse().fail().message("请不要擅自修改标签id");
        }

        // 验证标签信息

        if (!validateStaffLabel(staffLabel)) {
            return new FebsResponse().fail().message("标签信息不符合要求");
        }

        log.debug("修改标签id：" + staffLabel.getId());

        if (staffLabel.getId() == null) {
            throw new FebsException("标签ID为空");
        }

        staffLabel.setLastModifyUserId(FebsUtil.getCurrentUser().getUserId());
        staffLabel.setLastModifyDate(new Date());
        staffLabelService.updateStaffLabel(staffLabel);
        redisTemplate.delete(FebsUtil.getCurrentUser().getUserId() + "");
        return new FebsResponse().success();
    }

    /**
     * 导出excel
     * @param response
     * @param staffLabel
     */
    @GetMapping("staffLabel/excel")
    @ControllerEndpoint(exceptionMessage = "导出Excel异常")
    public void export(HttpServletResponse response, StaffLabel staffLabel) {
        List<StaffLabel> staffLabels = staffLabelService.getStaffLabelListNotPage(staffLabel);
        ExcelKit.$Export(StaffLabel.class, response).downXlsx(staffLabels, false);
    }


    /**
     * 将当前修改的标签id存起来，修改提交时进行比对
     * @param id
     */
    private void saveStaffLabelEditing(Integer id) {
        String currentUserId = "" + FebsUtil.getCurrentUser().getUserId();
        redisTemplate.opsForValue().set(currentUserId, id + "", 30, TimeUnit.MINUTES);
    }

    /**
     * 检测是否重名，重名则无法创建
     */
    @GetMapping("staffLabel/isRepetitive")
    @ResponseBody
    public Boolean isRepetitive(String staffLabelName) {
        return staffLabelService.isRepetitive(staffLabelName);
    }

    /**
     * 修改更新的数据格式,将数据放到页面里
     */
    private void resolveStaffLabelModel(Integer id, Model model, Boolean transform) {
        StaffLabel staffLabel = staffLabelService.getById(id);

        if (staffLabel.getCreateDate() != null) {
            model.addAttribute("standardCreateDateTime", DateUtil.getDateFormat(staffLabel.getCreateDate(), DateUtil.FULL_TIME_SPLIT_PATTERN));
        }

        if (staffLabel.getLastModifyDate() != null) {
            model.addAttribute("standardLastModifyDateTime", DateUtil.getDateFormat(staffLabel.getLastModifyDate(), DateUtil.FULL_TIME_SPLIT_PATTERN));
        }

        model.addAttribute("staffLabel", staffLabel);
    }

    /**
     * 验证标签信息
     * @param staffLabel
     * @return
     */
    private Boolean validateStaffLabel(StaffLabel staffLabel) {

        // 标签名是否符合格式
        if (!FebsUtil.match(TAG_NAME_REGEX, staffLabel.getStaffLabelName())) {
            return false;
        }

        // 标签备注是否符合格式
        if (staffLabel.getRemark() != null && staffLabel.getRemark().length() > REMARK_MAX_LENGTH) {
            return false;
        }

        return true;
    }

}
